# coding=utf-8
'''
Created on Nov 16, 2009
@author: gpossum
'''

import datetime
import logging
import types
from google.appengine.ext import db
#from google.appengine.api import users


class Account(db.Model):
    lastMenu = db.IntegerProperty()


class Note(db.Model):
    account = db.ReferenceProperty(Account)
    date = db.DateTimeProperty(required=True)
    title = db.StringProperty(required=True)
    note = db.StringProperty(required=True, multiline=True)
    status = db.StringProperty(required=True, default='new', choices=set(['new', 'active', 'complete', 'remove']))

class Word(db.Model):
    eng = db.StringProperty(required=True, default=u'unknown')
    eng_tr = db.StringProperty(default=u'')
    eng_ext = db.StringProperty(default=u'')
    rus = db.StringProperty(default=u'')
    rus_ext = db.StringProperty(default=u'')
    part = db.StringProperty(default=u'')
    pop = db.IntegerProperty()

    def __str__(self):
        return self.eng + ' [' + self.eng_tr + '] ' + self.part + '- ' + self.rus + self.rus_ext + ' (' + str(self.pop) + ')'


class WordAttr(db.Model):
    account = db.ReferenceProperty(Account)
    word = db.ReferenceProperty(Word)
    repeat = db.IntegerProperty(default=0)
    done = db.BooleanProperty(default=False)


def create_word(user, eng, eng_ext, rus, rus_ext):
    try:
        account = get_account(user)
        w = Word(account=account,
                 eng=eng,
                 eng_ext=eng_ext,
                 rus=rus,
                 rus_ext=rus_ext)
        w.put()
        return w
    except db.Error:
      logging.info('Error create word')
      return None

def get_word(word_id):
    word_id = _extractId(word_id)
    if word_id:
        word = Word.get_by_id(word_id)
        return word
    return None

def remove_word(word_id):
    word = get_word(word_id)
    if word:
        word.delete()


def get_words():
    #account = _get_or_create_account(user)
    words = Word.all().fetch(10)
    return words




def _get_or_create_account(user):
    """
    Find a matching Account or create a new one with the
    email as the key_name.
    
    Returns a Account for the given user.
    """
    if user is None:
        return None
    account = Account.get_by_key_name(user.email())
    if account is None:
        account = Account(key_name=user.email())
    logging.info('_get_or_create_account ' + str(account))
    return account

def get_account(user):
    if user is None:
        return None
    try:
        def tnx():
            account = _get_or_create_account(user)
            account.lastMenu = 0
            account.put()
            logging.info('get_account ' + str(account))
            return account
        return db.run_in_transaction(tnx)
    except db.Error:
        logging.error('get_account')
        return None



def create_note(user, title, note):
    #try:
        account = get_account(user)
        date = datetime.datetime.now()
        n = Note(account=account,
                 date=date,
                 title=title,
                 note=note,
                 status='new')
        n.put()
        logging.info('create_note ' + str(n))
        return n
    #except db.Error:
    #  return None

def get_note(note_id):
    note_id = _extractId(note_id)
    if note_id:
        note = Note.get_by_id(note_id)
        logging.info('get_note ' + str(note))
        return note
    return None

def remove_note(note_id):
    node = get_note(note_id)
    if node:
        node.delete()


def get_notes(user):
    account = _get_or_create_account(user)
    notes = Note.gql("WHERE account = :1", account).fetch(10)
    logging.info('get_notes ' + str(notes))
    return notes



def _extractId(str):
    try:
        if(isinstance(str, types.StringTypes)):
            str = long(str)
    except TypeError:
        logging.error('_extractId')
        return None

    if(isinstance(str, types.IntType) or
            isinstance(str, types.LongType)):
        return str
    return None





